/*
 * Report.java
 *
 * Created on April 8, 2007, 11:05 PM
 *
 * To change this template, choose Tools | Template Manager
 * and open the template in the editor.
 */

package assistedpostagger;

import java.io.BufferedReader;
import java.io.BufferedWriter;
import java.io.File;
import java.io.FileReader;
import java.io.FileWriter;
import java.io.IOException;
import java.util.ArrayList;
import java.util.Iterator;
import java.util.ListIterator;

/**
 *
 * @author Paul Arezina
 */
public class Report {
    
    protected ArrayList<Word> reportWords;
    protected ArrayList<String> reportSentences;
    protected int totalEditableWords;
    protected ListIterator<Word> ITReport;
    protected TimeInterval reportTime;
    protected boolean reportAssisted;
    
    /** Creates a new instance of Report */
    public Report() {
        
        reportWords = new ArrayList();
        reportSentences = new ArrayList();
        totalEditableWords = 0;
        reportTime = new TimeInterval();
        reportTime.startNow();
        reportAssisted = false;
        
    }
    
    protected int getWordIndex() {
        
        int i = ITReport.previousIndex();
        return i;
        
    }
    
    public int getWordPosition() {
        
        ListIterator<Word> tempIT = reportWords.listIterator(ITReport.nextIndex());
        int position = 0;
        
        while(tempIT.hasPrevious()) {
            Word tempWord = tempIT.previous();
            if (tempWord.isEditable())
                position++;
        }
        
        return position;
        
    }
    
    public Word nextWord() {
        
        Word tempWord = ITReport.next();
        while (!(tempWord.isEditable())) {
            
            tempWord = ITReport.next();
            
        }
        return tempWord;
        
    }
    
    public Word currentWord() {
        
        int i = this.getWordIndex();
        Word w = reportWords.get(i);
        return w;
        
    }
    
    public Word previousWord() {
        
        ITReport.previous();
        
        Word tempWord = ITReport.previous();
        while (ITReport.hasPrevious() && !(tempWord.isEditable()))
            tempWord = ITReport.previous();
        
        Word testWord = ITReport.next();
        while (!(testWord.isEditable()))
            testWord = ITReport.next();
        
        return tempWord;
        
    }
    
    public boolean isEndReport() {
        
        ListIterator<Word> tempIT = reportWords.listIterator(ITReport.previousIndex());
        
        Word tempWord = tempIT.next();
        
        while (tempIT.hasNext() && !(tempWord.isEditable()))
            tempWord = tempIT.next();
        boolean hasNext = tempIT.hasNext();
        return !(hasNext);
        
    }
    
    public boolean isBeginningReport() {
        
        ListIterator<Word> tempIT = reportWords.listIterator(ITReport.nextIndex());
        
        if (tempIT.hasPrevious()) {
            tempIT.previous();
            return !(tempIT.hasPrevious());
        } else {
            return true;
        }
        
    }
    
    public void setWordIndex(int currentWord) {
        
        ITReport = reportWords.listIterator();
        
        if (currentWord > totalEditableWords)
            currentWord = totalEditableWords;
        
        while (currentWord > 0) {
            
            Word tempWord = ITReport.next();
            if (tempWord.isEditable())
                currentWord--;
            
        }
        
    }
    
    public int getReportSize() {
        return totalEditableWords;
    }
    
    public int getReportSentenceCount() {
        return reportSentences.size();
    }
    
    public boolean isAnyReportUnknowns() {
        
        boolean isUnknown = false;
        
        ListIterator<Word> tempIT = this.reportWords.listIterator();
        
        while (tempIT.hasNext()) {
            
            Word tempWord = tempIT.next();
            if (tempWord.getPOS().equalsIgnoreCase("??")) {
                isUnknown = true;
            }
        }
        
        return isUnknown;
        
    }
    
    public void tagReportUnknown(ArrayList<String> validTags) {
        
        ListIterator<Word> tempIT = this.reportWords.listIterator();
        
        while (tempIT.hasNext()) {
            
            Word tempWord = tempIT.next();
            if (validTags.contains(tempWord.getPOS())) {
                tempWord.setPOS("??");
                tempIT.set(tempWord);
            }
        }
        
        
    }
    
    public void open(File infile, ArrayList<String> validTags) throws IOException {
        
        
        BufferedReader bfr = new BufferedReader(new FileReader(infile));
        String fileLine, lastPOS, wordPart, tagPart;
        boolean isWordTag;
        String tagTokens[];
        String thisToken[];
        Word thisWord;
        
        if (bfr.ready()) {
            reportWords.clear();
            reportSentences.clear();
            reportAssisted = false;
        }
        
        int sentenceCount = 0;
        int wordInSentenceCount = 0;
        totalEditableWords = 0;
        
        
        
        while(bfr.ready()) {
            fileLine = bfr.readLine();
            
            if (fileLine.equalsIgnoreCase("assist")) {
                reportAssisted = true;
            }
            if (fileLine.contains("/")) {
                tagTokens = fileLine.split("\\s");
                lastPOS = "STA";
                String sentenceTemp = new String();
                wordInSentenceCount = 0;
                for (int i = 0; i < tagTokens.length; i++) {
                    if (tagTokens[i].contains("/")) {
                        thisToken = tagTokens[i].split("/");
                        wordPart = thisToken[0];
                        tagPart = thisToken[1];
                        isWordTag = (validTags.contains(tagPart)); // tags have alphanumerics
                        
                        if ((lastPOS == "STA") || !(isWordTag)) {
                            sentenceTemp = sentenceTemp.concat(wordPart);
                        } else {
                            sentenceTemp = sentenceTemp.concat(" " + wordPart);
                        }
                        
                        thisWord = new Word();
                        
                        thisWord.setText(wordPart);
                        thisWord.setPOS(tagPart);
                        thisWord.setSentence(sentenceCount);
                        if (isWordTag) {
                            thisWord.setPrevPOS(lastPOS);
                            thisWord.setEditable(true);
                            thisWord.setPositionInSentence(wordInSentenceCount);
                            wordInSentenceCount++;
                            totalEditableWords++;
                            lastPOS = tagPart;
                        }
                        reportWords.add(thisWord);
                    }
                }
                reportSentences.add(sentenceTemp);
                sentenceCount++;
            }
        }
        
        ITReport = reportWords.listIterator();
        reportTime = new TimeInterval();
        reportTime.startNow();
        
        bfr.close();
        
    }
    
    public void save(File outfile) throws IOException {
        
        BufferedWriter bfw = new BufferedWriter(new FileWriter(outfile));
        
        String currentLine = "";
        
        Iterator<Word> ITreportSave = reportWords.iterator();
        
        reportTime.endNow();
        reportTime.computeInterval();
        bfw.write(reportTime.toString());
        
        while (ITreportSave.hasNext()) {
            
            Word thisWord = ITreportSave.next();
            if (thisWord.getPositionInSentence() == 0) {
                if (currentLine != "") {
                    bfw.write(currentLine);
                    bfw.newLine();
                    currentLine = "";
                }
            }
            
            String thisTuple = thisWord.getText() + "/" + thisWord.getPOS();
            if (currentLine != "") {
                currentLine = currentLine + " " + thisTuple;
            } else {
                currentLine = thisTuple;
            }
            
        }
        
        if (currentLine != "") {
            bfw.write(currentLine);
        }
        
        
        
        bfw.close();
        
    }
    
    public String getSentence(int sentenceNum) {
        
        return reportSentences.get(sentenceNum);
        
    }
    
    public int getCurrentSentenceNum() {
        
        ListIterator<Word> tempIT = reportWords.listIterator(ITReport.nextIndex());
        int snum = tempIT.previous().getSentence();
        
        return snum;
    }
    
    public int getTotalWords() {
        
        return this.totalEditableWords;
        
    }
    
    public String getPastCurrentSentence() {
        
        ListIterator<Word> tempIT = reportWords.listIterator(ITReport.nextIndex());
        String outPast = "";
        
        if (!(tempIT.hasPrevious()))
            return outPast;
        
        Word tempWord = tempIT.previous();
        
        while(tempWord.getPositionInSentence() != 0) {
            tempWord = tempIT.previous();
            outPast = tempWord.getText().concat(" ").concat(outPast);
        }
        
        return outPast;
        
    }
    
    public String getRemainderCurrentSentence() {
        
        ListIterator<Word> tempIT = reportWords.listIterator(ITReport.nextIndex());
        String outRest = "";
        
        if (!(tempIT.hasNext()))
            return outRest;
        
        Word tempWord = tempIT.next();
        
        while((tempWord.getPositionInSentence() != 0) && (tempIT.hasNext())) {
            outRest = outRest.concat(" ").concat(tempWord.getText());
            tempWord = tempIT.next();
        }
        if (tempWord.getPositionInSentence() != 0)
            outRest = outRest.concat(tempWord.getText());
        
        return outRest;
        
    }
    
    public String getWordTag() {
        
        return this.currentWord().getPOS();
        
    }
    
    public void updateCurrentTag(String newTag) {
        
        ListIterator<Word> tempIT = reportWords.listIterator(ITReport.nextIndex());
        Word tempWord = this.currentWord();
        tempWord.setPOS(newTag);
        
        this.reportWords.set(this.getWordIndex(), tempWord);
        
        if (tempIT.hasNext()) {
            tempWord = tempIT.next();
            while(tempIT.hasNext() && !(tempWord.isEditable())) {
                tempWord = tempIT.next();
            }
            if (tempWord.isEditable()) {
                if (!(tempWord.getPrevPOS().equalsIgnoreCase("STA"))) {
                    tempWord.setPrevPOS(newTag);
                    this.reportWords.set(tempIT.previousIndex(), tempWord);
                }
            }
        }
        
    }

    public boolean isReportAssisted() {
        return reportAssisted;
    }

    public void setReportAssisted(boolean reportAssisted) {
        this.reportAssisted = reportAssisted;
    }
    
    
}
